﻿using BunnyEater.Domain.Base;
using BunnyEater.Domain.SystemManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace BunnyEater.Repository.BaseRepository
{
    public interface IRepository<TEntity> where TEntity : KeyEntity
    {
        /// <summary>
        /// 登录查询
        /// </summary>
        /// <param name="account">账号</param>
        /// <returns></returns>
        Task<User?> GetUserForLoginAsync(string? account);

        /// <summary>
        /// 获取所有的数据集合
        /// </summary>
        /// <returns>返回数据集合</returns>
        Task<List<TEntity>> GetAllListAsync();

        /// <summary>
        /// 查询数据集合
        /// </summary>
        /// <returns></returns>
        IQueryable<TEntity> GetListQuery();

        /// <summary>
        /// 根据数据对象主键查询单条数据
        /// </summary>
        /// <param name="key">数据对象主键</param>
        /// <returns>返回单条数据对象</returns>
        Task<TEntity> GetEntityByIdAsync(KeyEntity key);

        /// <summary>
        /// 获取数据集合的总记录数
        /// </summary>
        /// <returns>返回数据集合的总记录数</returns>
        int GetTotalCount();

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">页码（从1开始）</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="predicate">查询条件</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="isAscending">是否升序</param>
        /// <returns>分页结果</returns>
        Task<Page<TEntity>> GetPagedListAsync(int pageIndex, int pageSize,
            Expression<Func<TEntity, bool>>? predicate = null,
            Expression<Func<TEntity, object>>? orderBy = null,
            bool isAscending = true);

        /// <summary>
        /// 分页查询（支持复杂排序）
        /// </summary>
        /// <param name="pageIndex">页码（从1开始）</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="predicate">查询条件</param>
        /// <param name="orderBy">排序表达式</param>
        /// <returns>分页结果</returns>
        Task<Page<TEntity>> GetPagedListAsync(int pageIndex, int pageSize,
            Expression<Func<TEntity, bool>>? predicate = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>? orderBy = null);

        /// <summary>
        /// 新增单条数据
        /// </summary>
        /// <param name="entity">需要新增的数据对象</param>
        /// <returns>返回新增数据的受影响行数</returns>
        Task<int> InsertEntityAsync(TEntity entity);

        /// <summary>
        /// 批量新增数据集合
        /// </summary>
        /// <param name="entities">需要新增的数据集合</param>
        /// <returns>返回新增数据的受影响行数</returns>
        Task<int> InsertEntityAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 更新数据对象
        /// </summary>
        /// <param name="entity">需要更新的数据对象</param>
        /// <returns>返回更新数据的受影响行数</returns>
        Task<int> UpdateEntityAsync(TEntity entity);

        /// <summary>
        /// 根据数据对象主键软删除数据对象
        /// </summary>
        /// <param name="key">数据对象主键</param>
        /// <returns>返回软删除数据的受影响行数</returns>
        Task<int> DeleteByIdAsync(KeyEntity key);

        /// <summary>
        /// 根据数据对象主键真删除数据对象
        /// </summary>
        /// <param name="key">数据对象主键</param>
        /// <returns>返回真删除数据的受影响行数</returns>
        Task<int> DeleteEntityAsync(KeyEntity key);

        /// <summary>
        /// 批量软删除数据集合
        /// </summary>
        /// <param name="ids">需要软删除的数据对象Id集合</param>
        /// <returns>返回软删除数据的受影响行数</returns>
        Task<int> BulkDeleteAsync(IEnumerable<Guid> ids);

        /// <summary>
        /// 执行SQL语句
        /// </summary>
        /// <param name="sqlStr">需要执行的SQL语句</param>
        /// <returns>返回受影响行数</returns>
        int ExecuteSQL(string sqlStr);

        /// <summary>
        /// 使用SQL脚本查询
        /// </summary>
        /// <param name="sqlStr">需要执行的SQL脚本</param>
        /// <param name="parameters">SQL脚本所需要的参数</param>
        /// <returns></returns>
        IQueryable<TEntity> FromSQL(string sqlStr, IEnumerable<object> parameters);

        /// <summary>
        /// 根据条件查询单条数据
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns>返回满足条件的第一条数据，如果不存在则返回 null</returns>
        Task<bool> GetEntityAsync(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// 修改状态
        /// </summary>
        Task<int> UpdateFieldAsync(KeyEntity key, string propertyName, object value);
    }
}
